package edu.hcmus.sow.web;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.validation.Valid;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import edu.hcmus.sow.dao.FolderDAO;
import edu.hcmus.sow.domain.Folder;
import edu.hcmus.sow.service.DocumentService;
import edu.hcmus.sow.utils.SecurityUtil;
import edu.hcmus.sow.web.document.FolderForm;

@Controller
public class RepositoryController {
   // ~ Instance fields
   // ================================================================================================
   @Autowired
   private DocumentService documentService;

   @Autowired
   private FolderDAO folderDAO;

   // ~ Methods
   // ================================================================================================
   @RequestMapping(value = { "/admin", "/admin/" })
   public String home() {
      return "forward:/admin/repositories";
   }

   @RequestMapping(value = "/admin/repositories")
   public String listRepositories() {
      return "admin/repositories";
   }

   @RequestMapping("/admin/repository/search")
   @ResponseBody
   public List<Map<String, String>> search() {
      List<Map<String, String>> result = new ArrayList<Map<String, String>>();
      List<Folder> repositories = documentService.getRepositories();

      for (Folder repo : repositories) {
         Map<String, String> map = new HashMap<String, String>();
         map.put("id", repo.getId().toString());
         map.put("name", repo.getName());
         map.put("description", repo.getDescription());
         map.put("createdDate", DateFormatUtils.format(repo.getCreatedDate(), "MM/dd/yyyy HH:mm:ss"));
         map.put("createdBy", repo.getUserByCreatedBy().getUsername());
         result.add(map);
      }

      return result;
   }

   @RequestMapping("/ajax/admin/repository")
   public ModelAndView displayRepository(@RequestParam(value = "id", required = false) Integer id) {
      FolderForm folderForm = new FolderForm();
      if (id != null) {
         Folder folder = documentService.getFolderByID(id);
         folderForm.setId(id);
         folderForm.setFolderName(folder.getName());
         folderForm.setDescription(folder.getDescription());
         // folderForm.setCreatedDate(folder.getCreatedDate().getTime());
         // folderForm.setCreatedBy(folder.getUserByCreatedBy());
      }

      ModelAndView mav = new ModelAndView();
      mav.addObject("folderForm", folderForm);
      mav.setViewName("controls/repository_form");
      return mav;
   }

   @RequestMapping(value = "/ajax/admin/repository/save", method = RequestMethod.POST)
   public ModelAndView saveRepository(@Valid FolderForm folderForm, BindingResult result) {
      validateRepository(folderForm, result);

      if (!result.hasErrors()) {
         Folder folder = documentService.saveRepository(folderForm.getId(), folderForm.getFolderName(),
               folderForm.getDescription());

         folderForm.setId(folder.getId());
      }

      ModelAndView mav = new ModelAndView();
      mav.addObject("folderForm", folderForm);
      mav.addObject("hasErrors", result.hasErrors());
      mav.setViewName("controls/repository_form");
      return mav;
   }

   @RequestMapping(value = "/ajax/admin/repository/delete", method = RequestMethod.POST)
   @ResponseBody
   public String deleteRepository(@RequestParam(value = "id", required = true) Integer id) {
      try {
         documentService.deleteFolder(id);
      } catch (Exception e) {
         e.printStackTrace();
         return "error";
      }
      return "success";
   }

   private void validateRepository(FolderForm folderForm, Errors errors) {
      if (!errors.hasFieldErrors("folderName")) {
         List<Folder> folders = folderDAO.findFolderByName(SecurityUtil.getCurrentClient(), folderForm.getFolderName());
         int folderId = folderForm.getId() == null ? -1 : folderForm.getId().intValue();
         if (folders.size() > 0 && folders.get(0).getId().intValue() != folderId) {
            errors.rejectValue("folderName", "err.folderName", "Repository name already exists.");
         }
      }
   }
}
